package com.ct.dao.common.hibernate;

import org.hibernate.Session;
import org.hibernate.Query;

import java.io.Serializable;
import java.util.Collection;

import com.ct.dao.common.Dao;
import com.ct.dao.common.ObjectProvider;
import com.ct.dao.utils.HolderUtil;
import com.ct.model.common.Entity;

/**
 * Created by IntelliJ IDEA.
 * User: nmkravchenko
 * Date: 22.10.2009
 * Time: 17:33:54
 * To change this template use File | Settings | File Templates.
 */
public class HibernateDaoImpl<PKType extends Serializable, E extends Entity<PKType>>
        implements Dao<PKType, E> {

    public HibernateDaoImpl(Class<E> aEntityClass, ObjectProvider<Session> aSessionHolder) {
        _entityClass = aEntityClass;
        _sessionHolder = aSessionHolder;
    }    

    @SuppressWarnings("unchecked")
    public E load(PKType aId) {
        return load(getEntityClass(), aId);
    }

    @SuppressWarnings("unchecked")
    public E load(Class<E> aClass, PKType aId) {
        return (E) getSession().get(aClass, aId);
    }

    public void save(E aEntity) {
        getSession().save(aEntity);
    }

    public void update(E aEntity) {
        getSession().update(aEntity);
    }

    public void saveOrUpdate(E aEntity) {
        getSession().saveOrUpdate(aEntity);
    }

    public void persist(E aEntity) {
        getSession().persist(aEntity);
    }

    @SuppressWarnings("unchecked")
    public E merge(E aEntity) {
        return (E) getSession().merge(aEntity);
    }

    public void delete(E aEntity) {
        getSession().delete(aEntity);
    }

    public Collection<E> findAll() {
    	return findAll(_entityClass);
    }

    public Collection<E> findAll(Class<E> aDictionaryClass) {
        Query query = getSession().createQuery("from " + aDictionaryClass.getSimpleName());
    	query.setCacheable(true);
    	query.setCacheRegion("dictionaryCacheRegion");
    	return query.list();
    }

    public Class<E> getEntityClass() {
        return _entityClass;
    }

    public void refresh(E aEntity) {
        getSession().refresh(aEntity);
    }

    protected Session getSession() {
        return HolderUtil.getRequired(_sessionHolder);
    }

    private Class<E> _entityClass;

    private ObjectProvider<Session> _sessionHolder;
}

